{
  LW Txtr -- LightWave Textures

  The Texture Functions global gives plug-ins access to LightWave®'s texture
  engine. A plug-in can create and use textures to modulate its parameters,
  and it can read and modify the settings of existing textures.

  Based on lwtxtr.h which is:
  Copyright 1999, NewTek, Inc.
}

{
  Copyright 2012, Jameel Halabi

  This unit is part of the BlaiseWave wrapper,
  which is licensed under the BSD 2-Clause license (see licenses/license.txt).
}

unit LW_Txtr;

{$mode objfpc}{$H+}

interface

uses
  LW_Types     ,
  LW_Render    ,
  LW_Meshes    ,
  LW_Envel     ,
  LW_IO        ,
  LW_Instancing;

const
  { Texture coordinate context:
      0 = any: all layers are evaluated.
      1 = object: only object coordinate layers will be evaluated
      2 = world: only world coordinate layers will be evaluated.
    The conetxt should usually be set to 0, unless the texture needs
    to be evaluated in 2 steps, which is unusual.                    }
  TCC_ANY     = 0 ;
  TCC_OBJECT  = 1 ;
  TCC_WORLD   = 2 ;

  // Input parameter Types
  LWIPT_FLOAT	       = 2 ;
  LWIPT_DISTANCE       = 3 ;
  LWIPT_PERCENT	       = 4 ;
  LWIPT_ANGLE	       = 5 ;

  // GParamDesc flags
  LWGF_FIXED_MIN       = 1 shl 0 ; // Min value fixed
  LWGF_FIXED_MAX       = 1 shl 1 ; // Max value fixed
  LWGF_FIXED_START     = 1 shl 2 ; // Start param value fixed
  LWGF_FIXED_END       = 1 shl 3 ; // End param value fixed
  LWGF_AUTOSIZE	       = 1 shl 4 ; // Autosize enabled
  LWGF_LINKED          = 1 shl 5 ; // Start & end param values linked to previous param

  // Item type
  LWGI_NONE	       = -1 ;
  LWGI_OBJECT	       =  0 ;
  LWGI_LIGHT	       =  1 ;
  LWGI_CAMERA	       =  2 ;
  LWGI_BONE	       =  3 ;
  LWGI_VMAP	       =  4 ;

  LWTEXTUREFUNCS_GLOBAL	= 'Texture Functions 4' ;

  // Layer Types
  TLT_IMAGE = 0 ;
  TLT_PROC  = 1 ;
  TLT_GRAD  = 2 ;

  // Return Types
  TRT_VECTOR		 = 0 ;
  TRT_COLOR		 = 1 ;
  TRT_PERCENT		 = 2 ;
  TRT_SCALAR		 = 3 ;
  TRT_DISPLACEMENT       = 4 ;

  // Parameter Tags
  // Tag Data Type

  // enum LWTextureTag
  TXTAG_POSI     =  0 ; // double [3]
  TXTAG_ROTA     =  1 ; // double [3]
  TXTAG_SIZE     =  2 ; // double [3]
  TXTAG_FALL     =  3 ; // double [3]
  TXTAG_PROJ     =  4 ; // int      *
  TXTAG_AXIS     =  5 ; // int      *
  TXTAG_WWRP     =  6 ; // double   *
  TXTAG_HWRP     =  7 ; // double   *
  TXTAG_COORD    =  8 ; // int      *
  TXTAG_IMAGE    =  9 ; // ImageID  *
  TXTAG_VMAP     = 10 ; // VMapID   *
  TXTAG_ROBJ     = 11 ; // LWItemID *
  TXTAG_OPAC     = 12 ; // double   *
  TXTAG_AA       = 13 ; // int      *
  TXTAG_AAVAL    = 14 ; // double   *
  TXTAG_PIXBLEND = 15 ; // int      *
  TXTAG_WREPEAT  = 16 ; // int      *
  TXTAG_HREPEAT  = 17 ; // int      *
  TXTAG_ACTIVE   = 18 ; // int      *
  TXTAG_INVERT   = 19 ; // int      *
  TXTAG_BLEND    = 20 ; // int      *
  TXTAG_INPUT    = 21 ; // int      *
  TXTAG_AUVN     = 22 ; // char     *
  TXTAG_AUVU     = 23 ; // char     *
  TXTAG_AUVC     = 24 ; // int      *
  TXTAG_AUVO     = 25 ; // char     *

  // Projection Modes
  // enum LWTextureProjection
  TXPRJ_PLANAR      =  0 ;
  TXPRJ_CYLINDRICAL =  1 ;
  TXPRJ_SPHERICAL   =  2 ;
  TXPRJ_CUBIC       =  3 ;
  TXPRJ_FRONT       =  4 ;
  TXPRJ_UVMAP       =  5 ;


  // Repeat Modes
  // enum LWTextureRepeatMode
  TXRPT_RESET  =  0 ;
  TXRPT_REPEAT =  1 ;
  TXRPT_MIRROR =  2 ;
  TXRPT_EDGE   =  3 ;


  // Blend Modes
  // enum LWTextureBlendMode
  TXBLN_NORMAL     =  0 ;
  TXBLN_SUBTRACT   =  1 ;
  TXBLN_DIFFERENCE =  2 ;
  TXBLN_MULTIPLY   =  3 ;
  TXBLN_DIVIDE     =  4 ;
  TXBLN_ALPHA      =  5 ;
  TXBLN_DISPLACE   =  6 ;
  TXBLN_ADD        =  7 ;

type

  TGCoreSurface  = record end     ;
  PLWSurf        = ^TGCoreSurface ;

  TTxtrLayer     = record end     ;
  PLWTLayer      = ^TTxtrLayer    ;

  TTxtrContext   = record end     ;
  PLWTxtrContext = ^TTxtrContext  ;

  PLWVertexIndexes = ^TLWVertexIndexes ;
  TLWVertexIndexes = record
    VertexIndexes  : array[0..3] of Integer ;
    Verts          : array[0..3] of PLWPnt  ; // Surrounding Vertex IDs.
    Weights        : array[0..3] of Single  ; // Vertex Weigths.
    SpotSizeWidth  : Single                 ; // Spot Size Width.
    SpotSizeHeight : Single                 ; // Spot Size Height.
  end;

  PLWMicropol = ^TLWMicropol ;
  TLWMicropol = record
    OPos             ,
    WPos             ,
    OScl             ,
    GNorm            ,
    WNorm            ,
    Ray              : array[0..2] of Double ;
    BumpHeight       ,
    TxVal            ,
    SpotSize         : Double                ;
    RaySource        : array[0..2] of Double ;
    RayLength        ,
    Cosine           : Double                ;
    OXfrm            ,
    WXfrm            : array[0..8] of Double ;       // Transformation Matrix
    ObjID            : PLWItem               ;       // Object ID
    SrfID            : PLWSurf               ;       // Surface ID (pointer size)
    Verts            : array[0..3] of PLWPnt ;       // Surrounding vertex IDs
    Weights          : array[0..3] of Single ;       // Vertex Weigths
    VertsWPos        : array[0..3 , 0..2] of Single ; // Vertex World Positions
    PolNum           ,                               // Polygon Number
    OAxis            ,                               // Dominant Axis in object
    WAxis            ,                               // World Coordinates
    Context          : Integer               ;       // Coordinates Context
    Illuminate       : TLWIlluminateFunc     ;
    RayTrace         : TLWRayTraceFunc       ;
    RayCast          : TLWRayCastFunc        ;
    RayShade         : TLWRayShadeFunc       ;
    UserData         : Pointer               ;
    Polygon          : PLWPol                ;
    VertexIndexes    : PLWVertexIndexes      ; // Indexs To Original Polygone Vertex Index and Prespective Weights.
    InstanceID       : PLWItemInstance       ;
  end;

  PLWTxtrParamDesc = ^TLWTxtrParamDesc ;
  TLWTxtrParamDesc = record
    Name           : PChar   ;  // Parameter name for gradient input POPUP
    Start          ,            // Start and End values for this parameter
    End_           : Double  ;
    Type_          ,            // Return type (unit)
    Flags          ,            // Gradient flags
    ItemType       : Integer ;  // Type of item used by gradient
    ItemID         : PLWItem ;  // Item used if any
    ItemName       : PChar   ;  // Item Name used if any
  end;

  GParamData        = Pointer ;

  PLWTxtrParamFuncs = ^TLWTxtrParamFuncs ;
  TLWTxtrParamFuncs = record
    ParamEvaluate   : function
                      (       Param    : PLWTxtrParamDesc ;
                              ParamNb  : Integer          ;
                              MP       : PLWMicropol      ;
                              Data     : GParamData       ) : Double     ;
    ParamTime       : function
                      (       UserData : Pointer          ;
                              Param    : PLWTxtrParamDesc ;
                              ParamNb  : Integer          ;
                              Time     : TLWTime          ;
                              Frame    : TLWFrame         ) : GParamData ;
    ParamCleanup    : procedure
                      (       Param    : PLWTxtrParamDesc ;
                              ParamNb  : Integer          ;
                              Data     : GParamData       ) ;
  end;

  PLWTextureFuncs = ^TLWTextureFuncs ;
  TLWTextureFuncs = record
    ContextCreate   : function
                      (       Funcs : PLWTxtrParamFuncs   ) : PLWTxtrContext ;
    ContextDestroy  : procedure
                      (       GC : PLWTxtrContext         ) ;
    ContextAddParam : procedure
                      (       GC : PLWTxtrContext         ;
                              PD : PLWTxtrParamDesc       ) ;

    Create          : function
                      (       ReturnType : Integer        ;
                        const Name       : PChar          ;
                              GC         : PLWTxtrContext ;
                              UserData   : Pointer        ) : PLWTexture ;
    Destroy         : procedure
                      (       Txtr       : PLWTexture     ) ;
    Copy            : procedure
                      (       To_        : PLWTexture     ;
                              From       : PLWTexture     ) ;
    Newtime         : procedure
                      (       Txtr       : PLWTexture     ;
                              Time       : TLWTime        ;
                              Frame      : TLWFrame       ) ;
    Cleanup         : procedure
                      (       Txtr       : PLWTexture     ) ;
    Load            : procedure
                      (       Txtr       : PLWTexture     ;
                        const LoadState  : PLWLoadState   ) ;
    Save            : procedure
                      (       Txtr       : PLWTexture     ;
                        const SaveState  : PLWSaveState   ) ;
    Evaluate        : function
                      (       Txtr       : PLWTexture     ;
                              MP         : PLWMicropol    ;
                              RV         : PDouble        ) : Double ;
    SetEnvGroup     : procedure
                      (       Txtr       : PLWTexture     ;
                              GrpID      : PLWChanGroup   ) ;

    FirstLayer      : function
                      (       Txtr       : PLWTexture     ) : PLWTLayer ;
    LastLayer       : function
                      (       Txtr       : PLWTexture     ) : PLWTLayer ;
    NextLayer       : function
                      (       Txtr       : PLWTexture     ;
                              LayerID    : PLWTLayer      ) : PLWTLayer ;
    LayerAdd        : function
                      (       Txtr       : PLWTexture     ;
                              LayerType  : Integer        ) : PLWTLayer ;
    LayerSetType    : procedure
                      (       LayerID    : PLWTLayer      ;
                              LayerType  : Integer        ) ;
    LayerType       : function
                      (       LayerID    : PLWTLayer      ) : Integer ;
    LayerEvaluate   : function
                      (       LayerID    : PLWTLayer      ;
                              MP         : PLWMicropol    ;
                              RV         : PDouble        ) : Double ;
    LayerEnvGroup   : function
                      (       LayerID    : PLWTLayer      ) : PLWChanGroup ;
    SetParam        : function
                      (       LayerID    : PLWTLayer      ;
                              Tag        : Integer        ;
                              Data       : Pointer        ) : Integer ;
    GetParam        : function
                      (       LayerID    : PLWTLayer      ;
                              Tag        : Integer        ;
                              Data       : Pointer        ) : Integer ;
    EvaluateUV      : procedure
                      (       LayerID    : PLWTLayer      ;
                              WAxis      ,
                              OAxis      : Integer        ;
                              OPos       ,
                              WPos       : array {[0..2]} of Double    ;
                              UV         : array {[0..1]} of Double    ) ;

    Noise          : function
                     (        P          : array {[0..2]} of Double    ) : Double ; // Returns Perlin's noise values in [0,1]
    UserData       : function
                     (       Txtr        : PLWTexture ) : Pointer      ;
    EnvGroup       : function
                     (       Txtr        : PLWTexture ) : PLWChanGroup ;

    Texture        : function
                     (       LayerID     : PLWTLayer  ) : PLWTexture     ;
    Name           : function
                     (       Txtr        : PLWTexture ) : PChar          ;  // const
    Type_          : function
                     (       Txtr        : PLWTexture ) : Integer        ;
    Context        : function
                     (       Txtr        : PLWTexture ) : PLWTxtrContext ;
    CurrentTime    : function
                     (       Txtr        : PLWTexture ) : TLWTime        ;
  end;

implementation

end.

